/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controladores;

import Controladores.exceptions.NonexistentEntityException;
import Controladores.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Appointment;
import entidades.Medicalrecord;
import java.util.ArrayList;
import java.util.List;
import entidades.Vacine;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author Gatoper
 */
public class MedicalrecordJpaController implements Serializable {

    public MedicalrecordJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Medicalrecord medicalrecord) throws PreexistingEntityException, Exception {
        if (medicalrecord.getAppointment() == null) {
            medicalrecord.setAppointment(new ArrayList<Appointment>());
        }
        if (medicalrecord.getVacine() == null) {
            medicalrecord.setVacine(new ArrayList<Vacine>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Appointment> attachedAppointment = new ArrayList<Appointment>();
            for (Appointment appointmentAppointmentToAttach : medicalrecord.getAppointment()) {
                appointmentAppointmentToAttach = em.getReference(appointmentAppointmentToAttach.getClass(), appointmentAppointmentToAttach.getId());
                attachedAppointment.add(appointmentAppointmentToAttach);
            }
            medicalrecord.setAppointment(attachedAppointment);
            List<Vacine> attachedVacine = new ArrayList<Vacine>();
            for (Vacine vacineVacineToAttach : medicalrecord.getVacine()) {
                vacineVacineToAttach = em.getReference(vacineVacineToAttach.getClass(), vacineVacineToAttach.getId());
                attachedVacine.add(vacineVacineToAttach);
            }
            medicalrecord.setVacine(attachedVacine);
            em.persist(medicalrecord);
            for (Appointment appointmentAppointment : medicalrecord.getAppointment()) {
                Medicalrecord oldMedicalrecordOfAppointmentAppointment = appointmentAppointment.getMedicalrecord();
                appointmentAppointment.setMedicalrecord(medicalrecord);
                appointmentAppointment = em.merge(appointmentAppointment);
                if (oldMedicalrecordOfAppointmentAppointment != null) {
                    oldMedicalrecordOfAppointmentAppointment.getAppointment().remove(appointmentAppointment);
                    oldMedicalrecordOfAppointmentAppointment = em.merge(oldMedicalrecordOfAppointmentAppointment);
                }
            }
            for (Vacine vacineVacine : medicalrecord.getVacine()) {
                Medicalrecord oldMedicalrecordOfVacineVacine = vacineVacine.getMedicalrecord();
                vacineVacine.setMedicalrecord(medicalrecord);
                vacineVacine = em.merge(vacineVacine);
                if (oldMedicalrecordOfVacineVacine != null) {
                    oldMedicalrecordOfVacineVacine.getVacine().remove(vacineVacine);
                    oldMedicalrecordOfVacineVacine = em.merge(oldMedicalrecordOfVacineVacine);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findMedicalrecord(medicalrecord.getId()) != null) {
                throw new PreexistingEntityException("Medicalrecord " + medicalrecord + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Medicalrecord medicalrecord) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Medicalrecord persistentMedicalrecord = em.find(Medicalrecord.class, medicalrecord.getId());
            List<Appointment> appointmentOld = persistentMedicalrecord.getAppointment();
            List<Appointment> appointmentNew = medicalrecord.getAppointment();
            List<Vacine> vacineOld = persistentMedicalrecord.getVacine();
            List<Vacine> vacineNew = medicalrecord.getVacine();
            List<Appointment> attachedAppointmentNew = new ArrayList<Appointment>();
            for (Appointment appointmentNewAppointmentToAttach : appointmentNew) {
                appointmentNewAppointmentToAttach = em.getReference(appointmentNewAppointmentToAttach.getClass(), appointmentNewAppointmentToAttach.getId());
                attachedAppointmentNew.add(appointmentNewAppointmentToAttach);
            }
            appointmentNew = attachedAppointmentNew;
            medicalrecord.setAppointment(appointmentNew);
            List<Vacine> attachedVacineNew = new ArrayList<Vacine>();
            for (Vacine vacineNewVacineToAttach : vacineNew) {
                vacineNewVacineToAttach = em.getReference(vacineNewVacineToAttach.getClass(), vacineNewVacineToAttach.getId());
                attachedVacineNew.add(vacineNewVacineToAttach);
            }
            vacineNew = attachedVacineNew;
            medicalrecord.setVacine(vacineNew);
            medicalrecord = em.merge(medicalrecord);
            for (Appointment appointmentOldAppointment : appointmentOld) {
                if (!appointmentNew.contains(appointmentOldAppointment)) {
                    appointmentOldAppointment.setMedicalrecord(null);
                    appointmentOldAppointment = em.merge(appointmentOldAppointment);
                }
            }
            for (Appointment appointmentNewAppointment : appointmentNew) {
                if (!appointmentOld.contains(appointmentNewAppointment)) {
                    Medicalrecord oldMedicalrecordOfAppointmentNewAppointment = appointmentNewAppointment.getMedicalrecord();
                    appointmentNewAppointment.setMedicalrecord(medicalrecord);
                    appointmentNewAppointment = em.merge(appointmentNewAppointment);
                    if (oldMedicalrecordOfAppointmentNewAppointment != null && !oldMedicalrecordOfAppointmentNewAppointment.equals(medicalrecord)) {
                        oldMedicalrecordOfAppointmentNewAppointment.getAppointment().remove(appointmentNewAppointment);
                        oldMedicalrecordOfAppointmentNewAppointment = em.merge(oldMedicalrecordOfAppointmentNewAppointment);
                    }
                }
            }
            for (Vacine vacineOldVacine : vacineOld) {
                if (!vacineNew.contains(vacineOldVacine)) {
                    vacineOldVacine.setMedicalrecord(null);
                    vacineOldVacine = em.merge(vacineOldVacine);
                }
            }
            for (Vacine vacineNewVacine : vacineNew) {
                if (!vacineOld.contains(vacineNewVacine)) {
                    Medicalrecord oldMedicalrecordOfVacineNewVacine = vacineNewVacine.getMedicalrecord();
                    vacineNewVacine.setMedicalrecord(medicalrecord);
                    vacineNewVacine = em.merge(vacineNewVacine);
                    if (oldMedicalrecordOfVacineNewVacine != null && !oldMedicalrecordOfVacineNewVacine.equals(medicalrecord)) {
                        oldMedicalrecordOfVacineNewVacine.getVacine().remove(vacineNewVacine);
                        oldMedicalrecordOfVacineNewVacine = em.merge(oldMedicalrecordOfVacineNewVacine);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = medicalrecord.getId();
                if (findMedicalrecord(id) == null) {
                    throw new NonexistentEntityException("The medicalrecord with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Medicalrecord medicalrecord;
            try {
                medicalrecord = em.getReference(Medicalrecord.class, id);
                medicalrecord.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The medicalrecord with id " + id + " no longer exists.", enfe);
            }
            List<Appointment> appointment = medicalrecord.getAppointment();
            for (Appointment appointmentAppointment : appointment) {
                appointmentAppointment.setMedicalrecord(null);
                appointmentAppointment = em.merge(appointmentAppointment);
            }
            List<Vacine> vacine = medicalrecord.getVacine();
            for (Vacine vacineVacine : vacine) {
                vacineVacine.setMedicalrecord(null);
                vacineVacine = em.merge(vacineVacine);
            }
            em.remove(medicalrecord);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Medicalrecord> findMedicalrecordEntities() {
        return findMedicalrecordEntities(true, -1, -1);
    }

    public List<Medicalrecord> findMedicalrecordEntities(int maxResults, int firstResult) {
        return findMedicalrecordEntities(false, maxResults, firstResult);
    }

    private List<Medicalrecord> findMedicalrecordEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Medicalrecord.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Medicalrecord findMedicalrecord(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Medicalrecord.class, id);
        } finally {
            em.close();
        }
    }

    public int getMedicalrecordCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Medicalrecord> rt = cq.from(Medicalrecord.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
